package Text4;

import java.util.Scanner;

public class Main {
   /* 现在要进行 m个操作，操作共有三种：
    C a b，在点 a和点 b之间连一条边，a和 b可能相等；
    Q1 a b，询问点 a和点 b是否在同一个连通块中，a
    和 b可能相等；Q2 a，询问点 a所在连通块中点的数量；*/
   /* 输入格式
    第一行输入整数 n和 m。
    接下来 m行，每行包含一个操作指令，指令为 C a b，Q1 a b 或 Q2 a 中的一种。
*/
    /*输出格式
    对于每个询问指令 Q1 a b，如果 a和 b在同一个连通块中，则输出 Yes，否则输出 No。
    对于每个询问指令 Q2 a，输出一个整数表示点 a所在连通块中点的数量 每个结果占一行。*/


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] p = new int[n+1];
        int[] size = new int[n+1];
        for (int i = 1; i <= n; i++) {
            p[i]=i;
            size[i]=1;
        }
        while(m-->0){
            String s = scanner.next();

            //合并集合
            if(s.equals("C")){
                int a = scanner.nextInt();
                int b = scanner.nextInt();
                if(find(p,b)!=find(p,a)){
                    size[find(p,b)]+=size[find(p,a)];
                }
                p[find(p,a)]=find(p,b);
            } else if (s.equals("Q1")) {
                int a = scanner.nextInt();
                int b = scanner.nextInt();
                if(find(p,a)==find(p,b)){
                    System.out.println("Yes");
                }else{
                    System.out.println("No");
                }
            } else{
                int a = scanner.nextInt();
                System.out.println(size[find(p,a)]);
            }
        }
    }

    //并查集的核心操作，寻找根节点祖先 + 路径压缩
    public static int find(int[] p, int x) {
        if (p[x] != x) {
            p[x] = find(p, p[x]);
        }
        return p[x];
    }
}
